var _global = require('global/global.js');
var _Scene = require('component/scene.js');
var _layout = require('tools/layout.js');
var _relative = _layout.relative;
var _TouchNode = require('event/touchnode.js').TouchNode;

var _Menu = require('scenes/menu.js');
var _Pane = require('scenes/widget/pane.js');
var _Settings = require('scenes/constants.js');
var _UserInfo = require('config/userinfo.js');
var _History = require('config/history.js');
var _Statistics = require('config/statistics.js');
var _FragmentConstance = require('./game/fragments/constance.js');
var _Constance = require('./game/constant.js');

var _BackListener = require('global/backlistener.js');
var TWEEN = require('./game/tweens.js');
var _Prefer = require('config/prefer.js');

// ==========================
// Game
// ==========================
var Game = _Scene.createScene(
    function () {
        var screen = _global.screen;
        var w = screen.width(), h = screen.height();
        this.setId('game');
        this.mLocal = _Constance.getLocal();

        // header
        this.mHeader = _Pane.newInstance();
        this.mHeader.setId('pane.header');

        this.mFooter = module.$('./game/fragments/footer.js', _FragmentConstance.footerSize);
        this.mHeader.setId('pane.footer');
        this.mLocal.add('ui.scene', this);
        this.mLocal.add('ui.header', this.mHeader);
        this.mLocal.add('ui.footer', this.mFooter);

        this.mUpdateSpeed = 1;

        // drawable
        if (this.mLocal.find('istoturial')) {
            this.mGameArea = module.$('./game/toturial/gamearea.js');
        } else {
            this.mGameArea = module.$('./game/gamearea.js');
        }

        this.mGameArea.on('gameover', this.onGameOver, this);
        this.mGameArea.setTouchMargin(65, 65, 65, 130);
        this.mGameArea.initGame();

        this.addChild(this.mBg = _global.colorNode('FFFFFF', w, h));
        this.addChild(this.mUnder = module.$('./game/underview.js'));// view slot
        this.addChild(this.mHeader);
        this.addChild(this.mFooter);
        this.addChild(this.mGameArea);

        // title created in gamearea
        this.mLocal.find('ui.title').querySelector('button').forEach(function (button) {
            button.on('click', this.onButtonClick, this);
        }, this);

        this.onSizeChange(w, h);
    }
);

// ---------------- empty touch implement
Game.prototype.setUpdateSpeed = function (speed) {
    this.mUpdateSpeed = speed;
};
Game.prototype.createEventNode = function () {
    return new _TouchNode(this);
};
Game.prototype.onTouch = function (event) {
    return false;
};

// ---------------- interact with game logic
Game.prototype.setTouchDelegate = function (delegate) {
    this.getEventNode().setDelegate(delegate);
};
Game.prototype.cancelTouchDelegate = function () {
    this.getEventNode().setDelegate(this);
};
Game.prototype.onButtonClick = function (button) {
    switch (button.getId()) {
        case 'retry':
            this.retryGame();
            break;
        case 'menu':
            this.showMenu(_History.getRecords(), false);
            break;
    }
    _global.cancelEvents();
};

// ---------------- game
Game.prototype.onGameOver = function () {
    _BackListener.setBlocking(true);
    this.mGameArea.setTouchEnable(false);

    // show no moves
    var nomove = module.$('./game/fragments/outofmove.js');
    this.mHeader.addFirst(nomove);
    nomove.show().delay(0.33).start();

    // swip screen...
    this.mFooter.showTip('SWIPE TO SEE YOUR SCORE!');

    // listen to user swips
    var swipe = module.$('./game/swiptrigger.js', true);
    swipe.on('finish', this.showGameScore, this);
    this.getEventNode().setDelegate(swipe);
};
// ---------------- end swipe
Game.prototype.showGameScore = function () {
    this.mHeader.dumpFragments();

    var score = module.$('./game/fragments/totalscore.js');
    this.mHeader.addFragment(score);

    this.getEventNode().setDelegate(module.$('./game/endswip.js', this));
    var popup = module.$('scenes/game/popupanima.js', this.mGameArea);

    popup.on('finish', this.waitSwipAndSign, this);
    popup.on('scorechange', score.updateScore, score);
};
// ---------------- popup anima
Game.prototype.waitSwipAndSign = function () {
    this.getEventNode().setDelegate(this);
    this.setUpdateSpeed(1);
    this.mFooter.showTip('SWIPE & SIGN YOUR NAME');

    // wait util user input a name
    var swipe = module.$('./game/dialogtrigger.js', true);
    this.getEventNode().setDelegate(swipe);

    _UserInfo.on('nameavaiable', this.onUserNameAvaiable, this);// input success
    _UserInfo.on('namecanceled', swipe.dialogDismiss, swipe);// input canceled
};
// ---------------- show menu
Game.prototype.onUserNameAvaiable = function (name) {
    _UserInfo.off('nameavaiable');
    _UserInfo.off('namecanceled');

    var counts = this.mGameArea.getCellsCount();
    var record = _History.createRecord(name, counts);
    var records = _History.addRecord(record);
    _Statistics.updateRecord(record);

    // show menu with retry
    this.showMenu(records, true);
};
Game.prototype.onSizeChange = function (w, h) {
    this.setSize(w, h);
    this.mBg.setSize(w, h);

    this.mHeader.resize(_FragmentConstance.headerSize);
    this.mFooter.resize(_FragmentConstance.footerSize);

    _relative.local.layoutTo(this.mHeader, 0.5, 1, this, 0.5, 1);
    _relative.local.layoutTo(this.mFooter, 0.5, 0, this, 0.5, 0, 0, _Settings.adsHeight);

    var margin = 20;
    var top = h - this.mHeader.height() - margin;
    var bottom = _Settings.adsHeight + this.mFooter.height();
    var remain = top - bottom;
    var center = bottom + remain * 0.58;// grid center
    var gridtop = center + this.mGameArea.height() * 0.5;
    if (gridtop > top) {
        center -= gridtop - top;
    }

    _relative.layout(this.mGameArea, 0.5, 0.5, w * 0.5, center);
    var apos = this.mGameArea.getPosition();
    var asize = this.mGameArea.getSize();
    this.mGameArea.setTouchMargin(
        apos[0],
        h - apos[1] - asize[1],
        w - apos[0] - asize[0],
        apos[1]
    );
};

// ---------------- update
Game.prototype.update = function (context) {
    //console.log('this.mUpdateSpeed', this.mUpdateSpeed);
    TWEEN.update(context.stride() * this.mUpdateSpeed);
};
Game.prototype.confirmExit = function () {
    this.mLocal.release();
};
Game.prototype.onEnter = function () {
    _BackListener.bindScene(this);
};
Game.prototype.showMenu = function (record, endgame) {
    if (endgame) {
        this.mLocal.release();
        _Menu.newInstance(record, true).showMenu(this);
    } else {
        _Menu.newInstance(record, false).showMenu(this);
    }
};
Game.prototype.retryGame = function () {
    var comfirm = require('scenes/confirm.js').newInstance(this);
    comfirm.turnsUp();
};
Game.prototype.onBackPressed = function () {
    if (this.mLocal.find('istoturial') && !_Prefer.isToturialfinished()) {
        return;
    }
    var comfirm = require('scenes/confirm.js').newInstance(this);
    comfirm.turnsUp();
};

module.exports = Game;